﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Data;

namespace Tilver.Data
{
    /// <summary>
    /// 数据库操作类扩展
    /// </summary>
    public static class DataExtension
    {
        /// <summary>
        /// 获取唯一的IDataReader对象映射的实体对象(T)
        /// （IDataReader对象中只包含一条记录）
        /// </summary>
        /// <typeparam name="T">IDataReader对象映射的实体对象类型</typeparam>
        /// <param name="reader">IDataReader对象</param>
        /// <param name="rowMapper">IDataReader对象到实体对象的映射方法，如果为null，则默认使用ColumnMapperAttribute定义的元数据进行反射获取实体对象</param>
        /// <returns></returns>
        public static T MapToSingle<T>(this IDataReader reader, Func<IDataReader, T> rowMapper = null)
        {
            if (rowMapper == null) rowMapper = RowMapper.GetRowMapper<T>();
            T ret = default(T);
            try
            {
                if (reader.Read())
                {
                    ret = rowMapper(reader);
                }
                if (reader.Read()) throw new ArgumentException("IDataReader记录不唯一。", "reader");
            }
            finally
            {
                reader.Close();
            }
            return ret;
        }

        /// <summary>
        /// 获取IDataReader对象映射的实体对象(T)集合（后执行）
        /// </summary>
        /// <typeparam name="T">IDataReader对象映射的实体对象类型</typeparam>
        /// <param name="reader">IDataReader对象</param>
        /// <param name="rowMapper">IDataReader对象到实体对象的映射方法，如果为null，则默认使用ColumnMapperAttribute定义的元数据进行反射获取实体对象</param>
        /// <returns></returns>
        public static IEnumerable<T> MapToMutil<T>(this IDataReader reader, Func<IDataReader, T> rowMapper = null)
        {
            if (rowMapper == null) rowMapper = RowMapper.GetRowMapper<T>();
            try
            {
                while (reader.Read())
                {
                    yield return rowMapper(reader);
                }
            }
            finally
            {
                reader.Close();
            }
        }
        /// <summary>
        /// 获取IDataReader对象映射的实体对象(T)集合（立即执行）
        /// </summary>
        /// <typeparam name="T">IDataReader对象映射的实体对象类型</typeparam>
        /// <param name="reader">IDataReader对象</param>
        /// <param name="rowMapper">IDataReader对象到实体对象的映射方法，如果为null，则默认使用ColumnMapperAttribute定义的元数据进行反射获取实体对象</param>
        /// <returns></returns>
        public static List<T> MapToList<T>(this IDataReader reader, Func<IDataReader, T> rowMapper = null)
        {
            return MapToMutil<T>(reader, rowMapper).ToList<T>();
        }
    }

}
